import React, { useRef, useState, useEffect } from 'react';
import { Slider } from 'antd';
import moment from 'moment';
// styles
import styles from './index.less';
// 自定义组件
import { playData } from './playdata';
// 公用方法及函数
import * as PIXI from '@/components/LEAFLET_SDK/libs/pixi.js-legacy';
import _ from 'lodash';
import {
  getSpriteTint,
  getShortLabelColor,
  getShortLabelSize,
  getShortLabelText,
  canShowSpriteText,
} from './transData';
import { targetImgUrl, defaultSpriteConfig } from './const';

let _utils = null,
  _instance = null;
let _option = {
  query: null,
  click: null,
  hover: null,
  mousemove: null,
  contextmenu: null,
  zoomLevel: 7,
  sprite: {
    tint: (record) => '0x6ffff', // MB颜色
    // mbbp
    text: {
      show: () => false,
      tint: () => '0x6ffff',
      size: () => 24,
      value: (record) => 'bp文字',
    },
  },
};
let _maxDataLength = 500; // 一次渲染多少个
const zoomToLenMap = new Map([
  [1, 5000],
  [2, 5000],
  [3, 5000],
  [4, 5000],
  [5, 5000],
  [6, 5000],
  [7, 5000],
  [8, 5000],
  [9, 5000],
  [10, 5000],
  [11, 5000],
  [12, 5000],
  [13, 5000],
  [14, 5000],
]);
let map = null;
const _textures = {}; // 缓存图标resources
let _project = null;

export default () => {
  const redraw = useRef(false);
  const [tsData, setTsData] = useState([]);

  const queryTSData = (data) => {};
  // 单机事件查找相应mb
  const findEventHittedTarget = (e) => {
    const utils = _utils;
    if (utils) {
      const interaction = utils?.getRenderer().plugins.interaction;
      const container = utils?.getContainer();
      const pointEvent = e.originalEvent;
      const pixiPoint = new PIXI.Point();
      interaction.mapPositionToPoint(
        pixiPoint,
        pointEvent.clientX,
        pointEvent.clinetY,
      );
      return interaction.hitTest(pixiPoint, container);
    } else {
      return null;
    }
  };
  // 加载资源
  const addResource = () => {
    const loader = PIXI.Loader.shared;
    Object.keys(targetImgUrl).forEach((k) => {
      const key = `normal-${k}`;
      !loader.resources[key] && loader.add(key, targetImgUrl[k]);
    });
    loader.load(() => {
      const { resources } = loader;
      Object.keys(resources).forEach((k) => (_textures[k] = resources[k]));
    });
  };
  // 获取地图显示区域
  const getMapViewArea = (viewBounds, zoom) => {
    const min = viewBounds.getSouthWest();
    const max = viewBounds.getNorthEast();
    let minlng = min.lng,
      minlat = min.lat,
      maxlng = max.lng,
      maxlat = max.lat;
    if (zoom && zoom > 6) {
      let lngInterval = (maxlng - minlng) / 4;
      let latInterval = (maxlat - minlat) / 4;
      minlng -= lngInterval;
      maxlng += lngInterval;
      minlat -= latInterval;
      maxlat += latInterval;
    }
    return { minlng, minlat, maxlng, maxlat };
  };
  // 绘制文字信息
  const dataTextPaint = (data) => {
    for (let i = 0; i < data.length; i++) {
      // frittsvg.addTExt....
    }
  };

  // 显示text
  const showTextPaint = (data) => {
    try {
      const isMapPaused = map?.mapPaused || false;
      if (isMapPaused) return;
      // 获取是否启用当前可是区域显示
      const isCurAreaFilter = map?.curAreaFilter;
      const zoom = map.getZoom();
      let arr = tsData || [];
      if (isCurAreaFilter) {
        const { minlng, minlat, maxlng, maxlat } = getMapViewArea(
          map.getBounds(),
          map.getZoom(),
        );
        arr = arr.filter((item) => {
          const { lng, lat } = item;
          return (
            lng >= minlng && lng <= maxlng && lat >= minlat && lat <= maxlat
          );
        });
      }
      // 当前层级小于5 不绘制label
      if (!zoom || zoom < 5) return false;
      if (arr.length < zoomToLenMap.get(zoom)) {
        dataTextPaint(arr);
      }
    } catch (e) {
      console.log(e);
    }
  };

  // 获取缩放
  const getInvScale = (targetZoom) => {
    try {
      const utils = _utils;
      const currtntZoom = targrtZoom || utils?.getMap?.getZoom();
      return currtntZoom / (utils.getScale(currtntZoom) * 1024);
    } catch (error) {
      console.log(error);
    }
  };

  // 获取地图是否暂停
  const getIsMapPaused = () => map?.mapPaused || false;

  // 初始化绑定事件
  const _onAdd = (utils, _instance) => {
    const map = utils.getMap();
    const zoom = map.getZoom();
    _project = utils.latlngToLayerPoint;
    map.on('movestart', () => {
      // 地图开始拖动
      if (zoom < _option.zoomLevel) {
        // _instance?.clear();
      }
    });
    map.on(
      'moveend',
      () => {
        // 地图拖动结束
        if (zoom < 14) {
          if (!getIsMapPaused() && utils) {
            const invScale = getInvScale();
            utils.getContainer().children.forEach((i) => {
              i.scale.set(invScale * defaultSpriteConfig.width);
            });
            reRender();
          }
          showTextPaint();
        }
      },
      false,
    );
    if (_option.onHover) {
      map.on(
        'mousemove',
        _.debounce((e) => {
          const isInPopup =
            e.originalEvent.path.findIndex(
              (i) => i.classList && i.classList.contains('leaflet-popup'),
            ) > -1;
          // 如果在popup里面移动 不做处理
          if (isInPopup) return false;
          const target = findEventHittedTarget(e) || {};
          _option.onHover(target.payload, !!target.payload || isInPopup);
        }, 800),
      );
    }
    if (_option.onContextMenu) {
      map.on('contextmenu', (e) => {
        const target = findEventHittedTarget(e) || {};
        if (target && target.payload) {
          _option.onContextMenu(target.payload, {
            x: e.originalEvent.x,
            y: e.originalEvent.y,
          });
        }
      });
    }
    if (_option.onClick) {
      map.on('click', (e) => {
        const target = findEventHittedTarget(e) || {};
        if (target && target.payload) {
          _option.onClick(target.payload, {
            x: e.originalEvent.x,
            y: e.originalEvent.y,
          });
        }
      });
    }
    if (_option.dblClick) {
      map.on('dblclick', (e) => {});
    }
  };

  // 清除所有sprite
  const removeAllSprite = () => {
    const utils = _utils;
    const container = utils.getContainer();
    const children = container.children;
    children.forEach((item) => {
      item.destory();
      item.children.forEach((child) => {
        child.destory({ texture: true, bastTexture: true });
      });
    });
    container.removeChildren();
  };

  // 创建sprite
  const createSprite = (item = {}) => {
    try {
      if (item.points) delete item.points;
      // 创建图标
      const textures = _textures['normal-flight'];
      const sprite = new PIXI.Sprite(textures['texture']);
      sprite.name = item.name;
      sprite.interaction = true;
      sprite.payload = item;
      const coords = _project([item.jd, item.wd]);
      sprite.anchor.set(0.5);
      sprite.scale.set(data.scale);
      sprite.x = coords.x;
      sprite.y = coords.y;
      sprite.interactive = true;
      sprite.buttonMode = true;
      sprite.payload = data.payload;
      return sprite;
    } catch (error) {
      console.log(error);
    }
  };

  // 添加Sprite
  const addSprite = (data, container, total) => {
    let invScale = getInvScale();
    const dataLength = data.length;
    for (let i = 0; i < dataLength; i++) {
      const sprite = createSprite(data[i]);
      if (_option.sprite.text.show(zoom, total)) {
        // frittsvg.addtext
      }
      sprite.scale.set(invScale * defaultSpriteConfig.width);

      container.addChild(sprite);
      sprite = null;
    }
  };

  // 绘制数据
  const dataPaint = async (data) => {
    try {
      const renderer = _utils?.getRenderer();
      const container = _utils?.getContainer();
      const count = data.length / _maxDataLength;
      if (redraw.current) return false;
      if (!getIsMapPaused) {
        await removeAllSprite();
        if (data.length < _maxDataLength) {
          await addSprite(data, container, data.length);
          renderer.render(container);
          redraw.current = true;
        } else {
          for (let i = 0; i < count; i++) {
            const start = i * _maxDataLength;
            const end = i + 1 > count ? data.length : start + _maxDataLength;
            await requestAnimationFrame(() => {
              addSprite(data.slice(start, end), container, data.length);
              if (end === data.length) {
                renderer.render(container);
                redraw.current = true;
              }
            });
          }
        }
        showTextPaint();
      }
    } catch (error) {
      console.log(error);
    }
  };

  // pixi图层创建好的回调
  const onPixiReady = (utils, event) => {
    _utils = utils;
    const renderer = utils.getRenderer();
    const container = utils.getContainer();
    const getScale = utils.getScale;
    switch (event.type) {
      case 'zoomend':
        break;
      case 'add':
        _onAdd(utils, _instance);
        break;
      case 'redraw':
        removeAllSprite();
        break;
      default:
        break;
    }
  };

  // 初始化pixioverlay
  const initPixiOverlay = () => {
    const option = {
      query: () => {},
      onClick: (points) => {},
      dblClick: () => {},
      onHover: () => {},
      onContextMenu: () => {},
      sprite: {
        tint: getSpriteTint,
        text: {
          show: canShowSpriteText,
          value: getShortLabelText,
          size: getShortLabelSize,
          tint: getShortLabelColor,
        },
      },
    };
    const pixiContainer = new PIXI.Container();
    pixiContainer.interaction = true;
    pixiContainer.buttonMode = true;
    _option = { ..._option, ...option };
    _instance = L.pixiOverlay(onPixiReady, pixiContainer, {
      autoPreventDefault: false,
    });
    _instance.addTo(map);
  };

  useEffect(() => {
    map = window?.LFTmap;
    addResource();
    initPixiOverlay();
    return () => {
      redraw.current = false;
      map.removeLayer(_instance);
      _instance.destory();
      removeAllSprite();
      _utils = null;
      _instance = null;
    };
  }, []);

  useEffect(() => {
    if (tsData && tsData.length > 0) {
      dataPaint(data);
    }
  }, [tsData]);

  return <div className={styles.pixiTestContainer}></div>;
};
